<template>
  <view class="calendar">
    <slot name="headCut"></slot>
    <view class="calendar-days">
      <view class="week-wrap">
        <view v-for="(day, index) in weekdays" :key="index" class="outer">
          <view class="week">{{ day }}</view>
        </view>
      </view>
      <!-- 没展开渲染 -->
      <view v-if="!isExpanded" class="date-wrap">
        <view v-for="(date, index) in weekData[atIndex]" :key="index" class="outer" @click="clickCalendar(date,index)">
          <view class="date">
            <view class="text" :class="{ active:  date.isToday }">{{ date.day }}</view>
            <view class="dot yes" v-if="date.showValue"></view>
          </view>
        </view>
      </view>
      <!-- 展开渲染 -->
      <view v-else class="date-wrap">
        <view v-for="(date, index) in yearData" :key="index" class="outer" @click="clickCalendar(date,index)">
          <view class="date">
            <view class="text" :class="{ active: date.isToday }">{{ date.day }}</view>
            <view :class="['dot',date.isNoDay ? 'no' : (date.showValue ? 'in' : '')]" ></view>
          </view>
        </view>
      </view>
    </view>
    <view class="calendar-header">
      <view @touchstart="toggleExpand" class="spread" v-if="hasOpenBut"/>
    </view>
    <u-datetime-picker :show="showPicker" v-model="selectedDate" mode="year-month" type="date" @confirm="onDateConfirm"
                       @cancel="onDateCancel" placeholder="选择年月"></u-datetime-picker>
  </view>
</template>

<script>
import dayjs from 'dayjs';

export default {
  name: "l-calendar",
  props: {
    year: {
      type: Number,
      default: dayjs().year()
    },
    month: {
      type: Number,
      default: dayjs().month() + 1
    },
    hasOpenBut: {
      type: Boolean,
      default: false
    },
    data: {
      type: Array,
      default: () => {
        return []
      }
    },
    valueDate: {
      type: Object,
      default: () => {
        return {}
      }
    },
    form: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  data() {
    return {
      // 是否展示日期选择
      showPicker: false,
      // 星期列表
      weekdays: ['日', '一', '二', '三', '四', '五', '六'],
      dates: [], // 日历数据
      firstWeekDates: [], // 存储第一周的日期
      isExpanded: true, // 控制日历展开和收缩
      // 当前年月
      atTime: '',
      // 折叠时展示的数据
      weekData: [],
      //当前周所在索引
      atIndex: 0,
      //整月天数
      yearData: [],
      selectedDate: '',
    };
  },
  created() {
    this.updateDates();
  },
  watch: {
    year(newValue, oldValue) {
      this.updateDates();
    },
    month(newValue, oldValue) {
      this.updateDates();
    },
    valueDate(newValue, oldValue) {
      this.handleMonth(newValue);
    }
  },
  methods: {
    // 更新日历
    updateDates(year = this.year, month = this.month, day = dayjs().date()) {
      const monthStr = month.toString().padStart(2, '0');
      this.selectedDate = dayjs(`${year}-${monthStr}-${day}`);
      //组合年月
      const startDate = dayjs(`${year}-${monthStr}-01`);
      this.atTime = `${year}-${monthStr}`;
      // 获取传入的月份的第一天是星期几
      const firstDayOfWeek = startDate.day();
      //当天是星期几
      this.activeIndex = dayjs().day();
      const totalDays = startDate.daysInMonth();
      // 生成完整的日期数组
      this.yearData = Array.from({length: totalDays + firstDayOfWeek}, (_, i) => {
        if (i < firstDayOfWeek) {
          return {}; // 补充空对象
        }
        const currentDate = startDate.add(i - firstDayOfWeek, 'day');
        const isToday = currentDate.isSame(dayjs(), 'day');
        return {
          date: currentDate.format("YYYY-MM-DD"),
          day: currentDate.format("D"),
          timesValue: currentDate.valueOf(),
          isToday: isToday,
          isNoDay: false,
          showValue: false,
        };
      });
      if (!this.isExpanded) {
        this.handleWeekList(this.yearData);
      }
    },
    //处理数组 一周为一个数组
    handleWeekList(data) {
      console.log(data)
      if (!this.more) {
        let result = []; // 用于存放结果的二维数组
        // 每次i增加7
        for (let i = 0; i < this.yearData.length; i += 7) {
          // 将从i开始的7个元素作为一个新的子数组加入到result中
          result.push(this.yearData.slice(i, i + 7));
        }
        this.weekData = result;
        this.arrLength = result.length;
        result.forEach((item, index) => {
          const found = item.some(o => o.isToday);
          if (found) {
            this.atIndex = index;
          }
        })
      }
    },
    // 确定
    onDateConfirm({value}) {
      this.selectedDate = value;
      this.showPicker = false;
    },
    // 展开收起
    toggleExpand() {
      this.isExpanded = !this.isExpanded;
    },
    // 展示控件
    handleShowPicker() {
      this.showPicker = true;
    },
    // 取消
    onDateCancel() {
      this.showPicker = false;
    },
    /** 传入的数据 判断日历是否显示 */
    handleMonth(data) {
      if (typeof data === 'object') {
        this.yearData.forEach((item, index) => {
          if (item) {
            const currentDate = dayjs(item.date);
            // 判断日期是否小于今天
            const minDay = currentDate.isBefore(dayjs(), 'day');
            if (data[item.date] && data[item.date] > 0) {
              item.showValue = true;
            }
            if (minDay && data[item.date]) {
              item.isNoDay = true;
            }
          }
        })
      }
    },
    /** 点击日历 */
    clickCalendar(e, index) {
      if (Object.keys(e).length === 0) return
      for (let i = 0; i < this.yearData.length; i++) {
        if (Object.keys(this.yearData[i]).length !== 0) {
          this.yearData[i].isToday = false;
        }
      }
      this.yearData[index].isToday = true;
      this.$emit('click', e)
    }
  }
};
</script>

<style lang="scss" scoped>
.calendar {
  background: #fff;

  &-header {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .year-month {
      flex: 1;
      display: flex;
      align-items: center;

      .arrow {
        width: 28rpx;
        height: 28rpx;
      }

      .time {
        margin: 0 40rpx;
        line-height: 36rpx;
        font-weight: 500;
        font-size: 28rpx;
        color: #181818;
      }
    }

    .spread {
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 20rpx 0 30rpx;
      flex: 1;

      &::after {
        content: "";
        width: 80rpx;
        height: 8rpx;
        background: #EFF1F8;
        border-radius: 200rpx;
      }
    }
  }

  &-days {
    padding-top: 20rpx;

    .week-wrap {
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 80rpx;
      box-sizing: border-box;

      .outer {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .week {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 60rpx;
        height: 60rpx;
        line-height: 60rpx;
        font-weight: 400;
        font-size: 28rpx;
        color: #acacac;
      }
    }

    .date-wrap {
      display: flex;
      flex-wrap: wrap;

      .outer {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 14.2857%;
        height: 100rpx;
        box-sizing: border-box;
      }

      .date {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        background: #fff;
        overflow: hidden;
        box-sizing: border-box;

        .text {
          width: 60rpx;
          height: 60rpx;
          border-radius: 50%;
          color: #fff;

          &.active {
            background: #2D64EB;
            color: #FFFFFF;
          }
        }

        .text {
          height: 60rpx;
          line-height: 60rpx;
          font-weight: 400;
          font-size: 28rpx;
          color: #181818;
          text-align: center;
        }

        .dot {
          margin-top: 10rpx;
          width: 8rpx;
          height: 8rpx;
          border-radius: 50%;
          background: transparent;

          &.yes {
            background-color: #3BE297;
          }

          &.no {
            background-color: #ACACAC;
          }

          &.in {
            background-color: #477EEC;
          }
        }
      }
    }
  }
}
</style>